Amazon Lex カスタムスロットタイプの「値を展開」と「スロット値に制限」の違いをまとめみた
はじめに
以前、Amazon Connect と Amazon Lex のカスタムスロットタイプを組み合わせて、電話での問い合わせを製品カテゴリーに応じて適切な担当者へ振り分けるチャットボットを作成し、その精度を検証しました。
振り分けは、Amazon Lex のカスタムスロットタイプに複数の製品カテゴリー名を事前に登録し、ユーザーの発話内容から特定の製品カテゴリーを判定させることで行います。
Amazon Lex カスタムスロットタイプでは、「値を展開」と「スロット値に制限」それぞれを検証しました。
それぞれの挙動に違いがあったため、今回は2つの違いをまとめます。
カスタムスロットタイプについて
カスタムスロットタイプは、Lexの会話をより柔軟にカスタマイズする機能です。
「値を展開」または「スロット値に制限」という2つの設定オプションがあります。
この機能を使うと、特定のインテント(ユーザーの意図)に対して、ユーザーから期待する回答の候補をリストとして定義できます。
例えば、「製品カテゴリー」というカスタムスロットタイプを作成し、その中に「スマートフォン」「タブレット」「ノートパソコン」などの値を定義できます。さらに、カスタムスロットタイプの「スロット値に制限」の場合、各値に対して同義語を明示的に設定することも可能です。「スマートフォン」に対して「スマホ」「携帯電話」といった同義語を定義できます。
各インテントには、ユーザーのリクエストを処理するために必要な情報を収集するためのパラメータ(スロット)を設定できます。このスロットにカスタムスロットタイプを割り当てることで、ボットは、 ユーザーの入力が「スマホについて教えて」の場合、「スマホ」を「スマートフォン」として認識し、スロット値に「スマートフォン」の値が入ります。
カスタムスロットタイプの特徴
-
柔軟性: 開発者が独自の値セットを定義できるため、特定のユースケースや業界に合わせたボットの作成が可能です。
-
精度の向上: 予めカスタムスロットタイプに定義された値のリストを使用することで、ユーザー入力の解釈(認識)精度が向上します。
-
一貫性のある値: スロットに入る値を制御することで、バックエンドシステムとの連携がスムーズになります。
-
同義語のサポート(「スロット値に制限」のみ): 各値に対して同義語を定義でき、ユーザーの多様な表現に対応できます。例えば、「スマートフォン」の同義語として「スマホ」「携帯電話」を定義できます。
-
値の展開またはスロット値の制限: カスタムスロットタイプでは、「値を展開」または「スロット値に制限」の2つの設定オプションがあり、ボットの動作を細かく制御できます。
本記事やAWSドキュメントでは、「ユーザー入力」というワードが度々出ますが、Amazon ConnectからLexを呼び出す場合、「ユーザー入力」は「ユーザーの発話を文字起こししたテキスト」とご認識ください。
カスタムスロットタイプの使用例
カスタムスロットタイプの具体的な使用例として、製品カテゴリーの識別を挙げます。複数の製品カテゴリー名をカスタムスロットタイプに登録することで、ボットはユーザーの入力をより正確に理解し、適切な応答を返すことができます。
以下の画像は、カスタムスロットタイプの2つの設定オプションを示しています
カスタムスロットタイプ「値を展開」の設定例
カスタムスロットタイプ「スロット値に制限」の設定例
「スロット値に制限」では、定義された値や同義語が設定できますが、「値を展開」では、同義語が設定できません。
「値を展開」では、ユーザーの入力がカスタムスロットタイプの値に完全に一致しなくても、類似した表現を認識できます。
一方、「スロット値に制限」では、定義された値や同義語に厳密に一致するユーザーの入力のみを受け付けます。
ユーザーの発話からスロット値決定までの流れ
Amazon ConnectからLexを呼び出し、ユーザーが発話してからスロット値が決定されるまでの一般的な流れを見てみましょう。
例では、ユーザーがお問い合わせ内容の中で製品カテゴリー名を伝え、製品カテゴリー名に応じて対応担当者を振り分けるケースです。
-
ユーザーの発話
ユーザーが発話します。- 例: "スマートフォンについて教えてください"
-
文字起こし(Transcription)
Lex で音声を文字に変換します。実際にはAmazon Transcribeでテキスト変換されてます。
テキストは、Lexの会話ログのうち、プロパティ名inputTranscript
に記録されます。- 例: "スマート フォン に つい て 教え て ください"
-
自然言語理解(NLU: Natural Language Understanding)
Lex が文字起こしされたテキストを解析し、インテントやスロットを識別します。 -
スロット値の抽出
文字起こし内容から、NLUで識別したスロットに対応する部分を抽出し、originalValue
に値が入ります。
例: originalValue = "スマート フォン" -
スロット値の解決
カスタムスロットタイプの設定(「値を展開」か「スロット値に制限」)に基づいて、
interpretedValue
とresolvedValues
を決定します。 -
最終的なスロット値の決定
interpretedValue
がスロットの最終的な値として使用されます。
この流れを踏まえた上で、3つのプロパティ(originalValueとinterpretedValue、resolvedValues)と「値を展開」、「スロット値に制限」の違い説明します。
スロット値に関する重要なプロパティ
スロット値に関連する3つの重要なプロパティを理解しましょう。AWSドキュメントに加え、検証した内容をもとに記載しています。
-
originalValue(元の値)
- ユーザーの入力のうち、Lexがスロットに対応していると判断した値です。
- 言い換えると、ユーザーの発話のうち、スロット値に対応していると判断された文字起こし箇所がそのまま値になります。
- 値の決定方法は、「値を展開」と「スロット値に制限」は同じです。
- ユーザーの入力のうち、Lexがスロットに対応していると判断した値です。
-
interpretedValue(解釈された値)
- Lexがスロットに対して決定する最終的な値です。この値がスロットに入ります。
- 値の決定方法は、「値を展開」か「スロット値に制限」によって異なります。
- 「値を展開」の場合、resolvedValuesのうち最初の値がinterpretedValueと一致します。
- 「スロット値に制限」の場合、originalValueがinterpretedValueと一致します。
-
resolvedValues(解決された値)
- ユーザーの入力のうち、Lexがカスタムスロットに定義された値や同義語の中から、スロットに対応していると判断した値のリストです。
- カスタムスロットに定義された値や同義語との一致度に基づいて生成されます。
- resolvedValuesには最大 5 つの値が含まれます。
- ユーザーの入力のうち、Lexがカスタムスロットに定義された値の中で、いずれかの値としても解釈できない場合、resolvedValuesが空になります。
- 値の決定方法は、「値を展開」か「スロット値に制限」によって異なります。
- 「値を展開」の場合
- resolvedValuesは、interpretedValueに影響しません。originalValueの値がinterpretedValueの値になります。
- 「スロット値に制限」の場合
- resolvedValuesリストの一番目の値がinterpretedValueの値になります。
- resolvedValuesが空の場合、interpretedValue(スロット値)が決まらないため、聞き返して、再度ユーザーの入力を求めます。
- 「値を展開」の場合
1. 「値を展開」(ORIGINAL_VALUE)
「値を展開」設定では、カスタムスロットタイプに定義された値は、Lexの機械学習モデルのトレーニングデータが利用されます。
これにより、Lex はカスタムスロットで定義された値に厳密に一致しない場合でも、類似した表現や関連する入力を認識し、適切なスロット値として解釈します。
特徴
- 「値を展開」は同義語の設定がなく、originalValueがそのまま interpretedValue(スロット値)となります
- ユーザーの入力値がカスタムスロットで定義した値に近い(resolvedValuesの値)場合でも、originalValueが優先されます。
- 「スロット値に制限」に比べ、より柔軟な入力を許容します。
メリット
- ユーザーの自然な言い回しをそのまま受け入れられます。
- 予期しない表現でも対応できる可能性があります
- ボット開発者は、カスタムスロットの値を定義する際に、ユーザーの多様な入力パターン(例:スペースの有無、略語、異なる表記)を全て網羅する必要がありません。Lexが類似表現を自動的に認識するため、開発の手間を軽減できます。
デメリット
- スロット値には、スペルミスや予期しない入力が含まれる可能性があります。
- 後処理で入力値の正規化が必要になる場合があります。
- スロットに入る値は、カスタムスロットタイプに定義された値ではないため、スペースなどが不要な値が入ることもあります。
2. 「スロット値に制限」(TOP_RESOLUTION)
「スロット値に制限」では、ユーザーの入力をカスタムスロットタイプに定義された値または同義語に厳密に一致させます。
これにより、Lexはユーザーの入力を予め定義された値に限定して解釈します。これは、正確性と一貫性が重要な場合や、特定の値のみを受け入れたい場合に有用です。
特徴
- ユーザーの入力は、カスタムスロットで定義したスロット値または同義語のいずれかでスロット値が解決されます。
- resolvedValuesリストの最初の値がinterpretedValue(スロット値)となります
- より厳密な入力制御が可能です。
メリット
- 一貫性のある値が得られます。
- バックエンドシステムとの連携が容易になります。
- カスタムスロットタイプに定義された値がスロットに入るため、予測可能な結果が得られます。
デメリット
- ユーザーの自然な表現が制限される可能性があります。
- 開発者は、カスタムスロットタイプに同義語や類似表現を網羅的に設定する必要があり、準備に時間がかかります。
- ユーザーの入力が定義された値と完全に一致しない場合(スペースの有無など)、Lexが解釈できず、再度の入力を求めます。
動作例の比較
「値を展開」と「スロット値に制限」において、実際の挙動を確認します。
動作例1
カスタムスロットに「スマートスピーカー」が定義されている場合
- ユーザーの発話: "スマートスピーカー"
- ユーザー入力(文字起こし): "スマート スピーカー"(スマートとスピーカーの間にスペースあり)
「値を展開」の場合
- 結果
- originalValue: "スマート スピーカー"
- interpretedValue(スロット値): "スマート スピーカー"
- resolvedValues: ["スマートスピーカー"]
Lexの会話ログの一部
"slots": {
"name": {
"value": {
"originalValue": "スマート スピーカー",
"interpretedValue": "スマート スピーカー",
"resolvedValues": [
"スマートスピーカー"
]
},
"inputTranscript": "スマート スピーカー",
「スロット値に制限」の場合
- カスタムスロットタイプの同義語の設定: 「スマート スピーカー」
- 結果
- originalValue: "スマート スピーカー"
- interpretedValue(スロット値): "スマートスピーカー"
- resolvedValues: ["スマートスピーカー"]
Lexの会話ログの一部
"slots": {
"name": {
"value": {
"originalValue": "スマート スピーカー",
"interpretedValue": "スマートスピーカー",
"resolvedValues": [
"スマートスピーカー"
]
},
"inputTranscript": "スマート スピーカー",
この例は、スペースを含む入力の扱いの違いを示しています。ユーザーが「スマートスピーカー」と発話した場合、文字起こしの結果が「スマート スピーカー」となることを前提としています。
「値を展開」設定では、文字起こしされた「スマート スピーカー」がそのままinterpretedValueとして使用されます。つまり、スペースを含んだ形でスロット値として扱われます。
一方、「スロット値に制限」設定では、事前に「スマート スピーカー」を同義語として適切に設定しておくことで、スペースを含む入力を正しく解釈し、カスタムスロットタイプに定義された「スマートスピーカー」という値に変換します。ちなみに、「スマート スピーカー」を同義語として設定していない場合、スロット値に値は入らず、ユーザーに再度聞き返します。
このように、「値を展開」はユーザー入力の形をそのまま維持し、「スロット値に制限」は定義された値に厳密に変換するという違いがあります。
動作例2
カスタムスロットに「スマートウォッチ」が定義されている場合
- ユーザーの発話: "スマートウォッチの件です"
- ユーザー入力(文字起こし): "スマート ウォッチ の 件 です"
「値を展開」の場合
- 結果
- originalValue: "スマート"
- interpretedValue(スロット値): "スマート"
- resolvedValues: ["スマートミラー","スマートプラグ","スマート体重計","スマートスピーカー","スマートホームデバイス"]
「スロット値に制限」の場合
- カスタムスロットタイプの同義語の設定: 「スマート ウォッチ」
- 結果
- originalValue: "スマート ウォッチ"
- interpretedValue(スロット値): "スマートウォッチ"
- resolvedValues: ["スマートウォッチ"]
「値を展開」設定では、Lexは「スマート」のみを認識し、「ウォッチ」を無視しています。その結果、interpretedValueは「スマート」となり、resolvedValuesには「スマート」で始まる他の製品カテゴリーが含まれますが、「スマートウォッチ」は含まれません。この状況では、ユーザーの実際の意図を正確に捉えられておらず、後処理で追加の解釈や確認が必要になります。
一方、「スロット値に制限」設定では、ユーザーの入力をカスタムスロットタイプに定義された値または同義語に厳密に一致させます。カスタムスロットタイプに「スマート ウォッチ」を同義語として事前に設定することで、Lexはこの入力を認識できます。Lexは入力を評価し、resolvedValuesリスト「スマートウォッチ」を生成します。このリストの最初の値がinterpretedValue(スロット値)となります。この方法により、定義された値に限定して解釈するため、正確性と一貫性が保たれます。
ただし、「スロット値に制限」設定で「スマート ウォッチ」を同義語として登録していない場合、Lexは一致するワードを見つけられず、resolvedValuesが空になります。その結果、interpretedValue(スロット値)が決定できないため、ユーザーに対して聞き直しが発生します。この厳密な制御は、特定の値のみを受け入れたい場合に有用ですが、適切な同義語の設定が重要となります。
動作例3
カスタムスロットに「スマートミラー」が定義されている場合
- ユーザーの発話: "スマートミラーについて話したいのですが"
- ユーザー入力(文字起こし): "マート ミラー に つい て 話し たい の です けど"
「値を展開」の場合
- 結果
- originalValue: "ミラー"
- interpretedValue(スロット値): "ミラー"
- resolvedValues: ["スマートミラー"]
「スロット値に制限」の場合
- カスタムスロットタイプの同義語の設定: 「スマート ミラー」
- 結果
- Lexは値を解決できず、ユーザーに再度入力を求めます。
- 会話ログ
{ "dialogAction": { "type": "ElicitSlot", "slotToElicit": "name" }, "intent": { "name": "ProductName", "slots": { "name": null } } }
音声認識の誤りや部分的な一致が発生した場合の両設定の挙動の違いを示しています。
「値を展開」では、部分的に一致した「ミラー」をスロット値として受け入れていますが、「スロット値に制限」では、完全一致しないため再入力を求めています。
この違いは、音声認識の精度が低い場合や、ユーザーの発話が不明瞭な場合に起こり得ます。
「値を展開」はより柔軟ですが、誤認識のリスクが高く、「スロット値に制限」はより正確ですが、事前に詳細な同義語設定が必要となります。
これらの例から、以下の違いが分かります。
- 「値を展開」は同義語の設定がないため、ユーザーの入力をそのまま interpretedValue として使用する傾向があります。
- 「スロット値に制限」は、カスタムスロットタイプに定義されたスロット値や同義語に厳密に一致する場合のみ値を設定し、それ以外の場合は再入力を求めます。
- 「値を展開」では、部分的な一致でも値を設定することがありますが、「スロット値に制限」ではより厳密な一致が求められます。
- 両方の設定で、文字起こしの精度が結果に大きく影響することがわかります。
- 「スロット値に制限」の場合、同義語やスペースを含む表現の登録が重要になります。
比較表
以下の表で、「値を展開」(ORIGINAL_VALUE)と「スロット値に制限」(TOP_RESOLUTION)の主な違いを比較します。
特性 | 値を展開(ORIGINAL_VALUE) | スロット値に制限(TOP_RESOLUTION) |
---|---|---|
interpretedValue の決定 | originalValue を使用 | resolvedValues の最初の値を使用 |
ユーザー入力の扱い | そのまま使用 | カスタムスロットで定義されたスロット値に変換 |
入力の柔軟性 | 高い(自由な入力を許容) | 低い(定義された値に制限) |
スロット値の一貫性 | 低い(ユーザーの入力によって異なる) | 高い(定義された値に統一) |
同義語定義の重要性 | -(設定できない) | 高い(多様な入力に対応するため) |
バックエンド連携の容易さ | やや難しい(不定形な値の処理が必要) | 容易(一貫した値が得られる) |
後処理の必要性 | 高い(正規化などが必要な場合がある) | 低い(定義された値が使用される) |
ユーザー体験 | より自然(自由な表現が可能) | やや制限的(定義された表現に限定) |
使い分けのポイント
-
「値を展開」を選ぶ場合
- ユーザーの多様な表現をそのまま活用したい場合
- 入力値の後処理や正規化が可能な場合
- より自然な会話体験を提供したい場合
- 判定できない場合、FallbackIntentを誘発し、「その他」と判定したい場合(参照)
-
「スロット値に制限」を選ぶ場合
- 厳密な値の制御が必要な場合
- バックエンドシステムとの連携で一貫した値が求められる場合
- 同義語や類似表現を網羅的に定義できる場合
- 判定できない場合、もう一度聞き返したい場合
実装上の注意点
- 「値を展開」使用時
- interpretedValue にはスペースが含まれる可能性があります。必要に応じて後処理でスペースを削除するなどの対応が必要です。
- resolvedValues が空の場合でも、interpretedValue には値が設定されることがあります。
- 「スロット値に制限」使用時
- 同義語の定義が重要です。ユーザーの多様な表現を想定し、できるだけ多くの同義語を登録しておくことが望ましいです。
- resolvedValues が空の場合、interpretedValue は null になります。この場合の処理(ユーザーに再度入力を求めるなど)を適切に実装する必要があります。
- 両方の設定に共通する注意点
- 文字起こし(inputTranscript)の精度が重要です。例えば、「スマート」が「マート」と認識されるなど、部分的な誤認識があった場合、スロット値の解決に影響を与える可能性があります。
- カスタムスロットタイプの定義時には、可能な限り多様な表現や同義語を含めることで、認識精度を向上させることができます。
まとめ
Amazon Lexのカスタムスロットタイプにおける「値を展開」と「スロット値に制限」の違いをまとめました。
originalValue、interpretedValue、resolvedValues の関係も理解して、アプリケーションの要件に応じて適切な設定を選択することが重要です。
ユーザー体験、バックエンドシステムとの連携、データの一貫性など、総合的に考慮し設計ください。